利用 Termux 和 Termux-API 在 Android 手机上定时自动更新壁纸
缘起
这个事情的需求,其实……就是闲得。
开个玩笑。我其实之前用 Tasker 这个 APP 做过类似的事情,见之前文章:分享一些自己DIY的task的profile,但是有一阵遇到了 android 手机的壁纸 bug,我的 pixel 给干挂了两回,其中有一回甚至给重制了才救回来,救回来之后就没起过自动更换壁纸的任务了。
这次是看到 V 站上有个大佬,展示自己极少的 APP 时,截图里展示了一个桌面,上面的壁纸上有格言,还有英文单词。于是我就自然而然的想要不要把毒鸡汤也写到壁纸上呢?:)
环境准备
Termux 和 Termux-API
我这里环境(Termux 和 Termux-API)是现成的,但如果没有需要安装的话,请记住,不要装 google play 上的 Termux 和 Termux-API,而是要装 F-Droid 这个市场上的 Termux 和 Termux-API!
注意:要给 Termux 足够的权限(也许 Termux-API 也需要):
- 后台运行的权限(不要被节电模式给干掉)
- 要设置为随机启动
最后,还要打开 Termux,输入:
1 | apt install termux-api; |
ImageMagick 及其他软件
打开 Termux,继续输入:
1 | apt install ImageMagick; |
具体实现
抓取毒鸡汤
毒鸡汤 也是我自己 fork 了某个大佬的代码,自己搭建的服务。本身没提供 API 服务,这里也没想再开发一个 API 接口,所以直接模拟 web 访问,然后把需要的数据抓出来即可。不过我们还需要手工折行。
定时抓取壁纸并处理(用 ImageMagick)
我自己有个壁纸服务:壁纸,会定时更新输出的壁纸,后台爬虫是用 go 实现的。
这里我就直接用了自己的这个壁纸服务,定时(每小时)去抓一个壁纸回来。接着做如下处理:
- 如果宽小于 1080 或者高小于 2400 的话,会首先被按原比例放大,直到宽达到 1080 或高达到 2400(具体看哪种放大的比率小)。
- 再接着在壁纸正中截取一个 1080x2400 的图片出来
- 最后在这个截取出来的 1080x2400 的图片的合适位置写上毒鸡汤服务中抓取出来的文本数据,把最终结果保存为文件
设置壁纸
最后自然是把上一步保留的文件用 termux-wallpaper 命令(来自于软件包 Termux-API)设置成新壁纸。
把整个工作自动化
把上面的流程写成代码(假设存为文件 $HOME/bin/change_wallpaper.sh),再用 termux-job-scheduler(来自于软件包 Termux-API)将这个代码设置为定时运行。我的例子里我是这样用的。打开 Termux,输入命令:
1 | termux-job-scheduler \ |
几个坑
中文字体
在图片上写中文(含全角标点)时需要用中文的字体,因为普通字体里没有中文字符呀!
所以,要在所有可用字体里选出有中文字符且全角标点位置不在中间的,其实还有个想法,就是想找一个酷一点的中文字体,我把所有可用字体做了个循环,测试写中文字符以及全角标点,结果保存到文件里,代码大概如下:
1 | for i in $(\ |
我先在我的 Mac 里跑的,找到一堆合适的字体以后,再去找 Termux 里 magick -list font | grep "Fonts:" | awk '{print $2}'
的结果来做对比,结果发现,匹配上的只有一种字体:Noto-Serif-CJK-SC。:(
当然,也可以再单独在 Termux 里安装新的好看的可用字体。但我没这么做,看以后需求吧。
crond vs termux-job-scheduler
其实最早这个方案我是打算用 crond 来做定时任务的,软件都安装设置好了。
打开 Termux,
1 | apt install cronie termux-services; |
关闭并重新打开 Termux
1 | sv-enable crond; |
但是发现用 crond 跑其他任务都没问题,但是跑 termux-API 里的命令总会报 Selinux 的错误!实在是搞不定啊,于是才转向 termux-job-scheduler 方案。
其实刚用 termux-job-scheduler 时日志里也出跟 crond 一样的信息,当时心就哇凉了,但没想到后来自己居然就好了?!:)
ImageMagick 的 -crop 跟 -gravity Center 一起用的问题
ImageMagick 软件包里的命令:convert 有个参数:*-crop*,功能是用来从图片上截取一部分,这个参数还需要提供 x、y 两个参数,这两个可以理解为横坐标(x)和纵坐标(y),这个时候学过一点点编程基础的小可爱们是不是自然而然都会以为 -crop 参数(其实是操作参数,可以理解为命令)截取的长方形图片是以这个横坐标 x、纵坐标y 为顶点的呢?
我一开始也是这么认为的,所以当我用 -gravity Center 将坐标零点设置为图片中心之后,我将参数 x 和 y 分别设置成了 -540 和 -1200,结果就悲催了,最后经过调试,才知道当有 -gravity Center 时,x 和 y 是指截取长方形的中心的坐标!!!!
所以,这里的 x 和 y 都应该是 0 才对!!
change_wallpaper.sh 代码
最后,show you the code:
1 |
|
最后,附壁纸截图一张: